package com.hl.card.modular.pack.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.hl.card.common.persistence.model.ReleaseScore;
import com.hl.card.common.persistence.model.ReleaseScoreDetail;
import com.hl.card.common.util.DateUtils;
import com.hl.card.common.util.ResponseData;
import com.hl.card.modular.pack.service.ScoreChangeService;

@Service
public class ScoreChangeServiceImpl implements ScoreChangeService {
	@Autowired
	private MongoTemplate mongoTemplate;
	@Autowired
	private RedisTemplate<String, Object> redisTemplate;
	@Autowired
	private RestTemplate restTemplate;
	private static String COLLECTION_NAME = "releaseScore"; // 释放比豆表
	public static String KEY = "redis_key_dict:";

	public Object getScoreInfo(Map<String, String> param) 
	{
		MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
		map.add("userId", param.get("userId"));
		map.add("cardType", param.get("cardType"));
		String result = restTemplate.postForEntity("http://payment-service/api/saCard/info", map, String.class).getBody();
		JSONObject o = (JSONObject) JSONObject.parse(result);
		long base_num = Long.parseLong(redisTemplate.opsForHash().get(KEY + "BDJH","BASE")+""); // 获取激活启动基数
		if (o.getInteger("code").equals(0)) // 成功
		{
			JSONObject obj = (JSONObject) o.get("obj");
			long remainPart = obj.getLong("remainPart"); // 总比豆数
			if (remainPart <= base_num) // 如果小于等于当前激活启动基数 例如激活比豆数5000 则不激活比豆
			{
				obj.put("cardLimit", remainPart);
				o.put("obj", obj);
			}
			
		}
		return o;
	
	}
	
	public ResponseData changeScore(Map<String, String> param) {
		ResponseData resultData = new ResponseData();
		MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
		map.add("userId", param.get("userId"));
		map.add("cardType", param.get("cardType"));

		String result = restTemplate.postForEntity("http://payment-service/api/saCard/info", map, String.class).getBody();
		JSONObject o = (JSONObject) JSONObject.parse(result);
		if (o.getInteger("code").equals(0)) // 成功
		{
			JSONObject obj = (JSONObject) o.get("obj");
			long remainPart = obj.getLong("remainPart"); // 总比豆数
			long base_num = Long.parseLong(redisTemplate.opsForHash().get(KEY + "BDJH","BASE")+""); // 获取激活启动基数
			if (remainPart <= base_num) // 如果小于等于当前激活启动基数 例如激活比豆数5000 则不激活比豆
			{
				resultData.setData(0);
				resultData.setStatus("1");
				resultData.setMsg("操作成功");
				return resultData;
			} else {

				Query query = Query.query(Criteria.where("user_id").is(param.get("userId"))); // 根据用户ID查找释放比豆数
				ReleaseScore socre = mongoTemplate.findOne(query,ReleaseScore.class, COLLECTION_NAME);
				long current_num =0l;
				long total_num=0l;
				if (socre == null) // 当前第一次未激活 直接释放基数5000
				{
					current_num=base_num;
					total_num=base_num;
					socre=new ReleaseScore();
					socre.setAdd_time(DateUtils.getNow("yyyy-MM-dd HH:mm:ss"));
					socre.setUser_id(param.get("userId"));
					socre.setTotal_score(current_num);
					List<ReleaseScoreDetail>  list=new ArrayList<ReleaseScoreDetail>();
					ReleaseScoreDetail  detail=new ReleaseScoreDetail();
					detail.setAdd_time(DateUtils.getNow("yyyy-MM-dd HH:mm:ss"));
					detail.setAdd_date(DateUtils.getNow("yyyy-MM-dd"));
					detail.setScore(current_num);
					list.add(detail);
					socre.setReleaseScoreDetailList(list);
					mongoTemplate.save(socre, COLLECTION_NAME);   //保存释放比豆数
				}else{
					Query query_date = Query.query(Criteria.where("user_id").is(param.get("userId")).and("releaseScoreDetailList.add_date").is(DateUtils.getNow("yyyy-MM-dd"))); // 根据用户ID查找当天释放比豆数
					ReleaseScore socre2 = mongoTemplate.findOne(query_date,ReleaseScore.class, COLLECTION_NAME);
					
					if(socre2!=null)
					{
						resultData.setData(0);      //今天已经释放过比豆 直接返回释放总数
						resultData.setStatus("1");
						resultData.setMsg("操作成功");
						return resultData;
					}
					long total_socre=socre.getTotal_score();
					String rate = (String) redisTemplate.opsForHash().get(KEY + "BDJH", "RATE"); // 获取激活比例
					String max_num = (String) redisTemplate.opsForHash().get(KEY + "BDJH", "MAX"); // 获取参与激活计算的比豆最高持有数
					if(remainPart>Long.parseLong(max_num))   //如果持有总数大于激活计算的比豆最高持有数
					{
						remainPart=Long.parseLong(max_num);
					}
					current_num=(long) ((remainPart - total_socre)* Double.parseDouble(rate)); // 获取当前需要释放的比豆数
					Update update=new Update();
					ReleaseScoreDetail scoreDetail=new ReleaseScoreDetail();
					scoreDetail.setAdd_date(DateUtils.getNow("yyyy-MM-dd"));
					scoreDetail.setAdd_time(DateUtils.getNow("yyyy-MM-dd HH:mm:ss"));
					scoreDetail.setScore(current_num);
					update.addToSet("releaseScoreDetailList",scoreDetail);
					long total= socre.getTotal_score().longValue();  //释放比豆总数
					total+=current_num;
					total_num=total;
					update.set("total_score", total);
					mongoTemplate.upsert(query,update,ReleaseScore.class, COLLECTION_NAME);
				}
		
				map.add("flag", "1");
				map.add("cardLimit", current_num + "");
				String result_change = restTemplate.postForEntity("http://payment-service/api/saCard/update", map,String.class).getBody();
				JSONObject o_change = (JSONObject) JSONObject.parse(result_change);
				if (o.getInteger("code").equals(0)) // 成功
				{
					resultData.setData(total_num);
					resultData.setStatus("1");
					resultData.setMsg("操作成功");
				}else {
					resultData.setData(null);
					resultData.setStatus("0");
					resultData.setMsg(o_change.getString("msg"));
					return resultData;
				}

			}
		} else {
			resultData.setData(null);
			resultData.setStatus("0");
			resultData.setMsg(o.getString("msg"));
			return resultData;
		}
		return resultData;

	}
}
